import Reflect from "@/utils/reflect";
import { AnyFunc } from "./type";

/** 延期执行 */
export function Deferred(timeout?: number) {

  return function (target: any, propertyKey: any, descriptor: TypedPropertyDescriptor<AnyFunc>) {
    Reflect.setValue(target, ["Deferred", propertyKey], descriptor.value);

    descriptor.value = function() {
      return async function (...args) {
        let timeId = Reflect.getValue<number | NodeJS.Timeout>(this, ["DeferredTimeId", propertyKey]);
        if (timeId) {
          clearTimeout(timeId);
        }
        timeId = setTimeout(() => {
          try {
            Reflect.getValue<AnyFunc>(target, ["Deferred", propertyKey]).call(this, ...args);
          } finally {
            Reflect.setValue(this, ["DeferredTimeId", propertyKey], undefined);
          }
        }, timeout);
        Reflect.setValue(this, ["DeferredTimeId", propertyKey], timeId);
      };
    }();

  };

}
